<style>
* {
    margin: 0px;
    padding: 0px;
}

.col-marleft {
    display: flex;
    justify-content: space-around;
}

.head_search {
    margin-bottom: 10px;
}
</style>
<template>
    <!-- 头部搜索 -->
    <div class="head_search">
        <el-row>
            <el-col :span="5">
                <el-input v-model="search" placeholder="请输入科室名称" />
            </el-col>
            <el-col :span="10">
                <!-- 搜索 -->
                <el-button type="primary" plain style="margin-left: 10px;" @click="getDataByName">
                    <el-icon>
                        <Search />
                    </el-icon>搜索
                </el-button>
                <!-- 打开添加弹窗 -->
                <el-button type="info" @click="dialogFormVisible = true" plain>
                    <el-icon>
                        <Plus />
                    </el-icon>添加
                </el-button>
            </el-col>
        </el-row>
    </div>
    <!-- 表格 -->
    【 <el-table :data="showInfo" row-key="deptId" style="width: 100%;">
        <el-table-column label="部门名称" prop="deptName" width="150" />
        <el-table-column label="负责人" prop="leader" />
        <el-table-column label="排序" prop="orderNum" width="100" />
        <el-table-column label="状态" prop="status" width="100" />
        <el-table-column label="创建时间" prop="createTime" />
        <el-table-column label="操作" align="center">
            <template #default="scope">
                <el-button size="small" plain type="success" @click="handleAdd(scope.$index, scope.row)"
                    :icon="Plus"><el-icon>
                        <CirclePlus />
                    </el-icon></el-button>
                <el-button size="small" type="primary" plain :icon="Edit" @click="handleEdit(scope.$index, scope.row)" />
                <el-button v-if="scope.row.parentId !== 0" size="small" type="danger" plain :icon="Delete"
                    @click="handleDelete(scope.$index, scope.row)" />
            </template>
        </el-table-column>
    </el-table>

    <!-- 添加/编辑Form -->
    <el-dialog v-model="dialogFormVisible" title="添加部门" :before-close="handleClose">
        <el-form :model="form" :label-position="labelPosition" class="demo-form-inline">
            <!-- 上级部门 -->
            <el-row class="col-marleft">
                <el-col :span="23">
                    <el-form-item label="上级部门">
                        <el-tree-select v-model="form.parentId" :data="options" check-strictly :render-after-expand="false"
                            style="width: 100%" placeholder="请选择科室" />
                    </el-form-item>
                </el-col>
            </el-row>
            <!-- 部门名称/显示排序-->
            <el-row class="col-marleft">
                <el-col :span="11">
                    <el-form-item label="部门名称">
                        <el-input v-model="form.deptName" placeholder="请输入部门名称" autocomplete="off" />
                    </el-form-item>
                </el-col>
                <el-col :span="11">
                    <el-form-item label="显示排序">
                        <el-input-number v-model="form.orderNum" style="width: 100%;" class="mx-4" :min="1"
                            controls-position="right" />
                    </el-form-item>
                </el-col>
            </el-row>

            <!-- 负责人/联系电话-->
            <el-row class="col-marleft">
                <el-col :span="11">
                    <el-form-item label="负责人">
                        <el-input v-model="form.leader" placeholder="请输入负责人" autocomplete="off" />
                    </el-form-item>
                </el-col>
                <el-col :span="11">
                    <el-form-item label="联系电话">
                        <el-input v-model="form.phone" placeholder="请输入联系电话" autocomplete="off" />
                    </el-form-item>
                </el-col>
            </el-row>

            <!-- 邮箱/部门状态-->
            <el-row class="col-marleft">
                <el-col :span="11">
                    <el-form-item label="邮箱">
                        <el-input v-model="form.email" placeholder="请输入邮箱" autocomplete="off" />
                    </el-form-item>
                </el-col>
                <el-col :span="11">
                    <el-form-item label="部门状态">
                        <el-radio-group v-model="form.status">
                            <el-radio label="0" name="states" border>正常</el-radio>
                            <el-radio label="1" name="states" border>停用</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </el-col>
            </el-row>

        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="handleClose">取消</el-button>
                <el-button type="primary" @click="btnSave">
                    提交
                </el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script setup>
import { computed, onMounted, ref, reactive, watch, Select, Option, Tree } from 'vue'
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Delete, Edit, Search, Share, Upload, Add } from '@element-plus/icons-vue'

//设置添加部门表单的input前文字
const labelPosition = ref('top')

//存储搜索框信息
var search = ref('');

//存储数据源数据
var tableData = ref([]);

//页面显示数据
var showInfo = ref([]);

//获取下拉菜单数据
const selectValue = ref();

//页面渲染后加载
onMounted(() => {
    bindData();
    //获取添加页面下拉框绑定
    axios.get('/api/system/dept/treeselect').then((item) => {
        options.value = convertIdToValue(item.data.data);
    })
});



//将下拉列表中的数据中id字段转为value   
function convertIdToValue(data) {
    // 递归终止条件：如果数据为空或者不是一个数组，则直接返回
    if (!data || !Array.isArray(data)) {
        return data;
    }

    // 递归处理每个元素
    return data.map((item) => {
        const newItem = { ...item };

        // 将 id 转换为 value
        if (newItem.id) {
            newItem.value = newItem.id;
            delete newItem.id;
        }

        // 递归处理子节点
        if (newItem.children) {
            newItem.children = convertIdToValue(newItem.children);
        }

        return newItem;
    });
}


//树形下拉菜单
const options = ref([]);


//保存数据
function btnSave() {

    axios({
        url: '/api/system/dept',
        method: form.deptId == 0 ? "post" : "put",
        data: form,
        headers: {
            'content-type': 'application/json'
        }
    }).then((res) => {
        var str = form.deptId == 0 ? "添加" : "修改";
        if (res.data.code == 200) {
            ElMessage({
                message: str + '成功',
                type: 'success',
            })
            clearForm();
            bindData();
        } else {
            ElMessage({
                message: str + '失败!' + res.data.msg,
                type: 'warning',
            })
        }
    }).catch(() => {
        ElMessage({
            message: '添加失败!网络异常',
            type: 'warning'
        })
    })


}

//新增
var handleAdd = (index, row) => {
    dialogFormVisible.value = true;
    form.parentId = row.deptId;
}

//编辑
var handleEdit = (index, row) => {
    Object.assign(form, row);
    dialogFormVisible.value = true;
}

//删除
var handleDelete = (index, row) => {
    var deptid = row.deptId;//删除数据的主键
    ElMessageBox.confirm(
        '确定要删除吗?',
        'Warning',
        {
            confirmButtonText: '确认',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        axios.delete(`/api/system/dept/${deptid}`).then(function (res) {
            // console.log(res);
            //返回格式：{code: 110, msg: "存在下级部门，不允许删除"}
            ElMessage({
                type: 'warning',
                message: res.data.msg
            })
        })

    }).catch(() => {
        ElMessage({
            type: 'info',
            message: '用户取消操作',
        })
    })
}


//添加、编辑 弹出层状态
var dialogFormVisible = ref(false)

//保存添加/编辑时的数据
var form = reactive({
    create_by: "",//创建者
    create_time: getNowDate(),//创建时间
    update_by: "",//更新者
    update_time: getNowDate(),//更新时间
    remark: "",//备注
    beginTime: getNowDate(),
    endTime: getNowDate(),
    deptId: 0,//部门idF
    parentId: 0,//父部门id
    ancestors: "",//祖级列表
    deptName: "",//部门名称
    orderNum: 0,//显示顺序
    leader: "",//负责人
    phone: "",//联系电话
    email: "",//邮箱
    status: "0",//部门状态（0正常 1停用）
    delFlag: "0"
});

//模态框关闭
const handleClose = () => {
    clearForm();
}

//关闭表单弹出层并清理表单中留存的数据
function clearForm() {
    //关闭弹出层
    dialogFormVisible.value = false;
    //格式化数据
    var info = {
        create_by: "",//创建者
        create_time: getNowDate(),//创建时间
        update_by: "",//更新者
        update_time: getNowDate(),//更新时间
        remark: "",//备注
        beginTime: getNowDate(),
        endTime: getNowDate(),
        deptId: 0,//部门id
        parentId: "",//父部门id
        ancestors: "string",//祖级列表
        deptName: "",//部门名称
        orderNum: 0,//显示顺序
        leader: "",//负责人
        phone: "",//联系电话
        email: "",//邮箱
        status: "0",//部门状态（0正常 1停用）
        delFlag: "0"
    }
    Object.assign(form, info)

}

//获取当前时间
function getNowDate() {
    const now = new Date();
    const year = now.getFullYear();
    const month = ('0' + (now.getMonth() + 1)).slice(-2);
    const day = ('0' + now.getDate()).slice(-2);
    const hours = ('0' + now.getHours()).slice(-2);
    const minutes = ('0' + now.getMinutes()).slice(-2);
    const seconds = ('0' + now.getSeconds()).slice(-2);
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}


//获取数据绑定
function bindData() {
    axios.get('/api/system/dept/list').then(function (res) {
        tableData.value = res.data.data;
        showInfo.value = buildTree(0);
    });
}

// 定义递归函数,处理表格中展示的数据
function buildTree(parentId) {
    var children = [];
    tableData.value.forEach((item) => {
        if (item.parentId === parentId) {
            item.children = buildTree(item.deptId); // 递归调用函数获取子节点
            children.push(item);
        }
    });
    return children;
}

//搜索
function getDataByName() {
    if (search.value.length == 0) {
        bindData();
    } else {
        console.log(showInfo.value);
        showInfo.value = handleTreeData(showInfo.value, search.value);
    }
}


//条件查询
function handleTreeData(treeData, searchValue) {

    if (!treeData || treeData.length === 0) {
        return [];
    }
    const array = [];
    for (let i = 0; i < treeData.length; i += 1) {
        let match = false;
        for (let pro in treeData[i]) {
            if (typeof (treeData[i][pro]) == 'string') {
                match |= treeData[i][pro].includes(searchValue);
                if (match) break;
            }
        }
        if (handleTreeData(treeData[i].children, searchValue).length > 0 || match) {
            array.push({
                //...：扩展运算符。对数组和对象而言，就是将运算符后面的变量里东西每一项拆下来。
                ...treeData[i],
                children: handleTreeData(treeData[i].children, searchValue),
            });
        }
    }
    return array;
}

</script>